﻿using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Domain.Services;
using YAPACS.BusinessObjects.Managements.Devices;
using YAPACS.BusinessObjects.Services;
using YAPACS.Organizations;
using YAPACS.RisServer.Abstractions;

namespace YAPACS.RisServer.Services;

public class DeviceService(
    IStationCodeProvider stationCodeProvider,
    ICurrentUserOrganization currentUserOrganization,
    IRepository<Device, Guid> deviceRepository,
    IRepository<Station, Guid> stationRepository,
    IRepository<Department, Guid> departmentRepository) : DomainService, IDeviceService, ITransientDependency
{
    private readonly string stationCode = stationCodeProvider.GetStationCode();

    private readonly ICurrentUserOrganization _currentUserOrganization = currentUserOrganization;
    private readonly IRepository<Device, Guid> _deviceRepository = deviceRepository;
    private readonly IRepository<Station, Guid> _stationRepository = stationRepository;
    private readonly IRepository<Department, Guid> _departmentRepository = departmentRepository;

    public async Task<Device> GetDeviceIfOnlyOneAsync(Guid? deviceTypeId = null)
    {
        if (!string.IsNullOrWhiteSpace(stationCode))
        {
            var station = await _stationRepository.FirstOrDefaultAsync(e => e.Code == stationCode && e.Room.IsActive && e.IsActive);
            if (station != null)
            {
                var devices = station.Devices
                    .Where(d => d.IsActive)
                    .WhereIf(deviceTypeId.HasValue, d => d.DeviceType.Oid == deviceTypeId)
                    .ToList();
                if (devices.Count == 1)
                {
                    return devices[0];
                }
            }
        }
        else
        {
            var department = await _departmentRepository.GetAsync(_currentUserOrganization.DepartmentId.Value);
            var devices = department.GetDevices()
                .WhereIf(deviceTypeId.HasValue, d => d.DeviceType.Oid == deviceTypeId)
                .ToList();
            if (devices.Count == 1)
            {
                return devices[0];
            }
        }
        return null;
    }

    public async Task<IList<Device>> GetDevicesAsync()
    {
        if (!string.IsNullOrWhiteSpace(stationCode))
        {
            var station = await _stationRepository.GetAsync(e => e.Code == stationCode && e.Room.IsActive && e.IsActive);
            return station.Devices.Where(d => d.IsActive).OrderBy(e => e.Order).ThenBy(e => e.CreationTime).ToList();
        }
        else
        {
            var department = await _departmentRepository.GetAsync(_currentUserOrganization.DepartmentId.Value);
            return department.GetDevices().ToList();
        }
    }

    public async Task<IList<Device>> GetDevicesAsync(Guid deviceTypeId)
    {
        var devices = await GetDevicesAsync();
        return devices.Where(e => e.DeviceType.Oid == deviceTypeId).ToList();
    }
}
